<?php
/**
 * Created by PhpStorm.
 * User: Levin
 * Date: 2018/3/15
 * Time: 下午3:49
 */
namespace plugins\payment\wechat;

class WechatSubmit
{
    public function unifiedOrder($no, $fee, $body, $open_id, $device="WEB")
    {
        $config = WechatConfig::fetchConfig();

        $openid = $open_id;
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        $data['appid'] = $config["appid"];
        $data['mch_id'] = $config["mch_id"]; //商户号
        $data['device_info'] = $device; //设备信息
        $data['body'] = $body; //商品简单描述
        $data['out_trade_no'] = $no; //订单号
        $data['total_fee'] = $fee; //订单总金额，单位为分
        $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; //APP和网页支付提交用户端ip
        $data['notify_url'] = $config["notify_url"]; //回调地址
        $data['trade_type'] = 'JSAPI';
        $data['openid'] = $openid;   //获取openid
        $data['nonce_str'] = $this->createNoncestr();
        $data['sign'] = $this->MakeSign($data);

        $xml = $this->ToXml($data);
//var_dump($data);
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        //设置header
        curl_setopt($curl, CURLOPT_HEADER, FALSE);

        //要求结果为字符串且输出到屏幕上
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($curl, CURLOPT_POST, TRUE); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        $tmpInfo = curl_exec($curl); // 执行操作
        curl_close($curl); // 关闭CURL会话
        $arr = $this->FromXml($tmpInfo);
//var_dump($arr);
        return $arr;
    }

    public function orderQuery($transaction_id)
    {
        $config = WechatConfig::fetchConfig();
        $url = "https://api.mch.weixin.qq.com/pay/orderquery";

        $data['appid'] = $config["appid"];
        $data['mch_id'] = $config["mch_id"]; //商户号
        $data['transaction_id'] = $transaction_id; //微信的订单号
        $data['nonce_str'] = $this->createNoncestr();
        $data['sign'] = $this->MakeSign($data);

        $xml = $this->ToXml($data);

        $result = $this->curl($url, $xml);
        $arr = $this->FromXml($result);

        if ($arr["return_code"] === "SUCCESS") {
            return $arr;
        } else {
            return [];
        }
    }

    protected function curl($url, $data="")
    {
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        //设置header
        curl_setopt($curl, CURLOPT_HEADER, FALSE);

        //要求结果为字符串且输出到屏幕上
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($curl, CURLOPT_POST, TRUE); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        $tmpInfo = curl_exec($curl); // 执行操作
        curl_close($curl); // 关闭CURL会话

        return $tmpInfo;
    }

    public function parseNotify($notify_xml)
    {
        return $this->FromXml($notify_xml);
    }

    /**
     *  产生随机字符串，不长于32位
     */
    public function createNonceStr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++)
        {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }

        return $str;
    }

    /**
     * 生成签名
     */
    public function MakeSign($arr)
    {
        //签名步骤一：按字典序排序参数
        ksort($arr);
        $string = $this->ToUrlParams($arr);

        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . WechatConfig::fetchConfig("make_sign");

        //签名步骤三：MD5加密
        $string = md5($string);

        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);

        return $result;
    }

    /**
     * 格式化参数格式化成url参数
     * @param $arr array
     * @return string
     */
    public function ToUrlParams($arr)
    {
        $buff = "";

        foreach ($arr as $k => $v)
        {
            if ($k != "sign" && $v != "" && !is_array($v))
            {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 输出xml字符
     * @param $arr array 组成xml的参数
     * @return string xml内容
     */
    public function ToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val)
        {
            if (is_numeric($val))
            {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
            else
            {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     * @return mixed
     */
    public function FromXml($xml)
    {
        //将XML转为array
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
}